<!--
 * Copyright © 2023
 * @Author: zhangxiang
 * @Date: 2023-02-09 17:10:18
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-02-13 16:50:27
 * @Description:
 *
-->

<template>
  <div class="file-uploader">
    <template v-if="status == 0">
      <el-button :disabled="disabled" @click="selectFile">{{
        btnText
      }}</el-button>
      <div v-if="hint" class="hint">{{ hint }}</div>
    </template>

    <div v-if="status == 1" :class="['file', disabled ? 'unable' : '']">
      <span class="name">{{ name }}</span>
      <span class="el-icon-circle-close icon" @click="inputFileCancel"></span>
    </div>

    <input
      ref="inputFile"
      style="display: none"
      :type="inputType"
      :accept="accept"
      @change="fileInputChangeFile"
    />
  </div>
</template>
<script>
import { isEmptyString } from '@/utils/index'

export default {
  name: 'FileUploader',
  props: {
    btnText: {
      type: String,
      default: '选择文件'
    },
    hint: {
      type: String,
      default: ''
    },
    file: {
      type: File,
      default: null
    },
    name: {
      type: String,
      default: ''
    },
    limitSize: {
      type: Number,
      default: 0 // 不限
    },
    accept: {
      type: String,
      default: '*'
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      inputType: 'file',
      status: 0 // 上传状态 0-等待选择 1-已选择 2-上传中 3-上传完成
    }
  },
  watch: {
    name: {
      handler(newValue) {
        if (!isEmptyString(newValue)) {
          this.status = 1
        }
      },
      immediate: true
    }
  },
  methods: {
    // 选择文件
    selectFile() {
      if (this.disabled) {
        return
      }
      this.$refs.inputFile.click()
    },
    // 取消已选择的文件
    inputFileCancel() {
      if (this.disabled) {
        return
      }
      this.status = 0
      this.$emit('update:file', null)
      this.$emit('update:name', '')
      this.inputType = 'text'
      setTimeout(() => {
        this.inputType = 'file'
      }, 100)
      this.$emit('cancel')
    },
    // 文件选择回调
    fileInputChangeFile(e) {
      const files = e.target.files
      if (files && files.length > 0) {
        if (
          this.limitSize <= 0 ||
          files[0].size / 1024 / 1024 < this.limitSize
        ) {
          this.$emit('update:file', files[0])
          this.$emit('update:name', files[0].name || 'fileNameDefault')
          this.status = 1
        } else {
          this.$message.warning('文件大小超出' + this.limitSize + 'M')
        }
      } else {
        this.inputFileCancel()
        this.$message.warning('选择文件出错，请重新选择')
      }
    }
  }
}
</script>

<style lang="less" scoped>
.file-uploader {
  display: flex;
  align-items: center;
  .hint {
    margin-left: 10px;
    color: #c0c4cc;
    font-size: 14px;
  }

  .file {
    display: flex;
    align-items: center;
    color: #565656;
    font-size: 14px;

    &.unable {
      color: #c0c4cc;
      cursor: not-allowed;

      .icon {
        cursor: not-allowed;
      }
    }

    .name {
      max-width: 400px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .icon {
      width: 22px;
      height: 22px;
      line-height: 22px;
      margin-left: 10px;
      cursor: pointer;
    }
  }
}
</style>
